#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
学生信息管理系统 - 优化版
重构后的模块化版本，提供更好的性能、可维护性和用户体验
"""

import os
import sys
import signal
from typing import Optional, Dict, Any
from datetime import datetime

# 添加当前目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from models import SystemConfig, User
from data_manager import DataManager
from auth_manager import AuthManager
from ui_manager import MenuManager, DataDisplayManager, FormManager, MessageManager
from analytics import StatisticsCalculator, ReportGenerator, ChartGenerator
from utils import logger, input_helper, display_helper
from exceptions import ValidationError, DataNotFoundError, PermissionError, AuthenticationError


class StudentManagementSystem:
    """学生信息管理系统主类"""
    
    def __init__(self, config_file: str = "config.json"):
        """初始化系统"""
        self.config = self._load_config(config_file)
        self.data_manager = DataManager(self.config)
        self.auth_manager = AuthManager(self.data_manager)
        self.menu_manager = MenuManager(self.auth_manager)
        self.display_manager = DataDisplayManager()
        self.form_manager = FormManager()
        self.message_manager = MessageManager()
        self.statistics_calculator = StatisticsCalculator()
        self.report_generator = ReportGenerator(self.data_manager)
        self.chart_generator = ChartGenerator()
        
        # 设置信号处理
        signal.signal(signal.SIGINT, self._signal_handler)
        signal.signal(signal.SIGTERM, self._signal_handler)
        
        # 创建默认管理员账户
        self._create_default_admin()
        
        logger.info("学生信息管理系统初始化完成")
    
    def _load_config(self, config_file: str) -> SystemConfig:
        """加载配置文件"""
        try:
            if os.path.exists(config_file):
                import json
                with open(config_file, 'r', encoding='utf-8') as f:
                    config_data = json.load(f)
                return SystemConfig.from_dict(config_data)
            else:
                # 创建默认配置
                config = SystemConfig()
                self._save_config(config, config_file)
                return config
        except Exception as e:
            logger.warning(f"加载配置文件失败，使用默认配置: {e}")
            return SystemConfig()
    
    def _save_config(self, config: SystemConfig, config_file: str):
        """保存配置文件"""
        try:
            import json
            with open(config_file, 'w', encoding='utf-8') as f:
                json.dump(config.to_dict(), f, ensure_ascii=False, indent=2)
        except Exception as e:
            logger.error(f"保存配置文件失败: {e}")
    
    def _create_default_admin(self):
        """创建默认管理员账户"""
        if not self.data_manager.users:
            try:
                admin_user = User(
                    username="admin",
                    password_hash=User.hash_password("admin123"),
                    role="admin"
                )
                self.data_manager.users.append(admin_user)
                self.data_manager.save_all_data()
                logger.info("默认管理员账户已创建: admin/admin123")
            except Exception as e:
                logger.error(f"创建默认管理员账户失败: {e}")
    
    def _signal_handler(self, signum, frame):
        """信号处理器"""
        logger.info(f"接收到信号 {signum}，正在安全退出...")
        self.shutdown()
        sys.exit(0)
    
    def run(self):
        """运行主程序"""
        try:
            print("欢迎使用学生信息管理系统！")
            print("作者：方旺 | 学号：20250101 | 班级：23A | 专业：土木工程")
            
            while True:
                try:
                    # 显示主菜单
                    menu_text = self.menu_manager.show_main_menu()
                    print(menu_text)
                    
                    # 获取用户选择
                    if not self.auth_manager.current_session:
                        choice = self.menu_manager.get_user_choice(2)
                        if choice == 0:  # Ctrl+C
                            break
                        elif choice == 1:
                            self._handle_login()
                        elif choice == 2:
                            break
                    else:
                        # 根据用户角色显示相应菜单
                        current_user = self.auth_manager.get_current_user()
                        if current_user.role == 'admin':
                            choice = self.menu_manager.get_user_choice(10)
                            if choice == 0:
                                break
                            self._handle_admin_choice(choice)
                        elif current_user.role == 'teacher':
                            choice = self.menu_manager.get_user_choice(7)
                            if choice == 0:
                                break
                            self._handle_teacher_choice(choice)
                        elif current_user.role == 'student':
                            choice = self.menu_manager.get_user_choice(6)
                            if choice == 0:
                                break
                            self._handle_student_choice(choice)
                
                except KeyboardInterrupt:
                    print("\n操作已取消")
                    continue
                except Exception as e:
                    self.message_manager.handle_exception(e)
                    input("\n按回车键继续...")
        
        except Exception as e:
            logger.error(f"程序运行出错: {e}")
            self.message_manager.show_error(f"程序运行出错: {e}")
        finally:
            self.shutdown()
    
    def _handle_login(self):
        """处理登录"""
        try:
            username = input_helper.get_input("请输入用户名: ")
            password = input_helper.get_input("请输入密码: ")
            
            if self.auth_manager.login(username, password):
                self.message_manager.show_success(f"登录成功！欢迎 {username}")
            else:
                self.message_manager.show_error("登录失败")
        except AuthenticationError as e:
            self.message_manager.show_error(str(e))
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _handle_admin_choice(self, choice: int):
        """处理管理员选择"""
        try:
            if choice == 1:
                self._user_management()
            elif choice == 2:
                self._student_management()
            elif choice == 3:
                self._course_management()
            elif choice == 4:
                self._grade_management()
            elif choice == 5:
                self._data_analysis()
            elif choice == 6:
                self._data_import_export()
            elif choice == 7:
                self._system_settings()
            elif choice == 8:
                self._show_system_status()
            elif choice == 9:
                self._logout()
            elif choice == 10:
                self.shutdown()
                sys.exit(0)
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _handle_teacher_choice(self, choice: int):
        """处理教师选择"""
        try:
            if choice == 1:
                self._query_students()
            elif choice == 2:
                self._course_management()
            elif choice == 3:
                self._grade_management()
            elif choice == 4:
                self._data_analysis()
            elif choice == 5:
                self._show_system_status()
            elif choice == 6:
                self._logout()
            elif choice == 7:
                self.shutdown()
                sys.exit(0)
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _handle_student_choice(self, choice: int):
        """处理学生选择"""
        try:
            if choice == 1:
                self._view_personal_info()
            elif choice == 2:
                self._query_grades()
            elif choice == 3:
                self._calculate_gpa()
            elif choice == 4:
                self._show_system_status()
            elif choice == 5:
                self._logout()
            elif choice == 6:
                self.shutdown()
                sys.exit(0)
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _user_management(self):
        """用户管理"""
        while True:
            options = [
                "添加用户",
                "删除用户",
                "修改用户",
                "查询用户",
                "显示所有用户",
                "返回主菜单"
            ]
            print(self.menu_manager.show_submenu("用户管理", options))
            choice = self.menu_manager.get_user_choice(6)
            
            if choice == 1:
                self._add_user()
            elif choice == 2:
                self._delete_user()
            elif choice == 3:
                self._update_user()
            elif choice == 4:
                self._query_user()
            elif choice == 5:
                self._display_all_users()
            elif choice == 6:
                break
    
    def _add_user(self):
        """添加用户"""
        try:
            user_data = self.form_manager.get_user_input()
            user = self.auth_manager.create_user(**user_data)
            self.data_manager.save_all_data()
            self.message_manager.show_success(f"用户 {user.username} 添加成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _delete_user(self):
        """删除用户"""
        try:
            username = input_helper.get_input("请输入要删除的用户名: ")
            user = self.data_manager.get_user(username)
            if not user:
                raise DataNotFoundError(f"用户 {username} 不存在", "user")
            
            if user.username == self.auth_manager.get_current_user().username:
                raise ValidationError("不能删除当前登录用户")
            
            if input_helper.confirm(f"确认删除用户 {username}？"):
                # 这里需要实现删除用户的逻辑
                self.message_manager.show_success(f"用户 {username} 删除成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _update_user(self):
        """修改用户"""
        try:
            username = input_helper.get_input("请输入要修改的用户名: ")
            user = self.data_manager.get_user(username)
            if not user:
                raise DataNotFoundError(f"用户 {username} 不存在", "user")
            
            print(f"当前用户信息: {user}")
            new_student_id = input_helper.get_input(f"新学号 [{user.student_id}]: ")
            
            if new_student_id:
                user.student_id = new_student_id
                self.data_manager.save_all_data()
                self.message_manager.show_success(f"用户 {username} 修改成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _query_user(self):
        """查询用户"""
        try:
            username = input_helper.get_input("请输入用户名: ")
            user = self.data_manager.get_user(username)
            if user:
                print(f"用户信息: {user}")
            else:
                self.message_manager.show_error(f"用户 {username} 不存在")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _display_all_users(self):
        """显示所有用户"""
        try:
            self.display_manager.display_users_table(self.data_manager.users)
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _student_management(self):
        """学生管理"""
        while True:
            options = [
                "添加学生",
                "删除学生",
                "修改学生",
                "查询学生",
                "显示所有学生",
                "返回主菜单"
            ]
            print(self.menu_manager.show_submenu("学生管理", options))
            choice = self.menu_manager.get_user_choice(6)
            
            if choice == 1:
                self._add_student()
            elif choice == 2:
                self._delete_student()
            elif choice == 3:
                self._update_student()
            elif choice == 4:
                self._query_students()
            elif choice == 5:
                self._display_all_students()
            elif choice == 6:
                break
    
    def _add_student(self):
        """添加学生"""
        try:
            student_data = self.form_manager.get_student_input()
            student = self.data_manager.add_student(student_data)
            self.data_manager.save_all_data()
            self.message_manager.show_success(f"学生 {student.name} 添加成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _delete_student(self):
        """删除学生"""
        try:
            student_id = input_helper.get_input("请输入要删除的学号: ")
            if input_helper.confirm(f"确认删除学号 {student_id} 的学生？"):
                self.data_manager.delete_student(student_id)
                self.data_manager.save_all_data()
                self.message_manager.show_success(f"学号 {student_id} 的学生删除成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _update_student(self):
        """修改学生"""
        try:
            student_id = input_helper.get_input("请输入要修改的学号: ")
            student = self.data_manager.get_student(student_id)
            if not student:
                raise DataNotFoundError(f"学号 {student_id} 不存在", "student")
            
            print(f"当前学生信息: {student}")
            update_data = {}
            
            new_name = input_helper.get_input(f"新姓名 [{student.name}]: ")
            if new_name:
                update_data['name'] = new_name
            
            new_age = input_helper.get_input(f"新年龄 [{student.age}]: ")
            if new_age and new_age.isdigit():
                update_data['age'] = int(new_age)
            
            new_major = input_helper.get_input(f"新专业 [{student.major}]: ")
            if new_major:
                update_data['major'] = new_major
            
            new_class = input_helper.get_input(f"新班级 [{student.class_name}]: ")
            if new_class:
                update_data['class_name'] = new_class
            
            if update_data:
                self.data_manager.update_student(student_id, update_data)
                self.data_manager.save_all_data()
                self.message_manager.show_success(f"学号 {student_id} 的学生修改成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _query_students(self):
        """查询学生"""
        try:
            print("\n=== 查询学生 ===")
            print("1. 按学号查询")
            print("2. 按姓名查询")
            print("3. 按专业查询")
            print("4. 按班级查询")
            print("5. 多条件查询")
            
            choice = self.menu_manager.get_user_choice(5)
            
            if choice == 1:
                student_id = input_helper.get_input("请输入学号: ")
                students = self.data_manager.search_students(student_id=student_id)
            elif choice == 2:
                name = input_helper.get_input("请输入姓名: ")
                students = self.data_manager.search_students(name=name)
            elif choice == 3:
                major = input_helper.get_input("请输入专业: ")
                students = self.data_manager.search_students(major=major)
            elif choice == 4:
                class_name = input_helper.get_input("请输入班级: ")
                students = self.data_manager.search_students(class_name=class_name)
            elif choice == 5:
                criteria = {}
                student_id = input_helper.get_input("学号（可选）: ")
                if student_id:
                    criteria['student_id'] = student_id
                
                name = input_helper.get_input("姓名（可选）: ")
                if name:
                    criteria['name'] = name
                
                major = input_helper.get_input("专业（可选）: ")
                if major:
                    criteria['major'] = major
                
                class_name = input_helper.get_input("班级（可选）: ")
                if class_name:
                    criteria['class_name'] = class_name
                
                age_min = input_helper.get_input("最小年龄（可选）: ")
                if age_min and age_min.isdigit():
                    criteria['age_min'] = int(age_min)
                
                age_max = input_helper.get_input("最大年龄（可选）: ")
                if age_max and age_max.isdigit():
                    criteria['age_max'] = int(age_max)
                
                students = self.data_manager.search_students(**criteria)
            
            if students:
                self.display_manager.display_students_table(students)
            else:
                self.message_manager.show_info("未找到匹配的学生")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _display_all_students(self):
        """显示所有学生"""
        try:
            self.display_manager.display_students_table(self.data_manager.students)
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _course_management(self):
        """课程管理"""
        while True:
            options = [
                "添加课程",
                "删除课程",
                "修改课程",
                "查询课程",
                "显示所有课程",
                "返回主菜单"
            ]
            print(self.menu_manager.show_submenu("课程管理", options))
            choice = self.menu_manager.get_user_choice(6)
            
            if choice == 1:
                self._add_course()
            elif choice == 2:
                self._delete_course()
            elif choice == 3:
                self._update_course()
            elif choice == 4:
                self._query_course()
            elif choice == 5:
                self._display_all_courses()
            elif choice == 6:
                break
    
    def _add_course(self):
        """添加课程"""
        try:
            course_data = self.form_manager.get_course_input()
            course = self.data_manager.add_course(course_data)
            self.data_manager.save_all_data()
            self.message_manager.show_success(f"课程 {course.course_name} 添加成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _delete_course(self):
        """删除课程"""
        try:
            course_id = input_helper.get_input("请输入要删除的课程代码: ")
            course = self.data_manager.get_course(course_id)
            if not course:
                raise DataNotFoundError(f"课程代码 {course_id} 不存在", "course")
            
            # 检查是否有相关成绩记录
            related_grades = self.data_manager.search_grades(course_id=course_id)
            if related_grades:
                if input_helper.confirm(f"该课程有 {len(related_grades)} 条成绩记录，确认删除课程及其所有成绩记录？"):
                    # 删除相关成绩记录
                    self.data_manager.grades = [g for g in self.data_manager.grades if g.course_id != course_id]
                    # 删除课程
                    self.data_manager.courses = [c for c in self.data_manager.courses if c.course_id != course_id]
                    self.data_manager.save_all_data()
                    self.message_manager.show_success(f"课程 {course_id} 及相关成绩记录删除成功")
            else:
                if input_helper.confirm(f"确认删除课程 {course_id}？"):
                    self.data_manager.courses = [c for c in self.data_manager.courses if c.course_id != course_id]
                    self.data_manager.save_all_data()
                    self.message_manager.show_success(f"课程 {course_id} 删除成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _update_course(self):
        """修改课程"""
        try:
            course_id = input_helper.get_input("请输入要修改的课程代码: ")
            course = self.data_manager.get_course(course_id)
            if not course:
                raise DataNotFoundError(f"课程代码 {course_id} 不存在", "course")
            
            print(f"当前课程信息: {course}")
            update_data = {}
            
            new_name = input_helper.get_input(f"新课程名称 [{course.course_name}]: ")
            if new_name:
                update_data['course_name'] = new_name
            
            new_credits = input_helper.get_input(f"新学分 [{course.credits}]: ")
            if new_credits and new_credits.replace('.', '').isdigit():
                update_data['credits'] = float(new_credits)
            
            new_teacher = input_helper.get_input(f"新授课教师 [{course.teacher}]: ")
            if new_teacher:
                update_data['teacher'] = new_teacher
            
            if update_data:
                for key, value in update_data.items():
                    setattr(course, key, value)
                self.data_manager.save_all_data()
                self.message_manager.show_success(f"课程 {course_id} 修改成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _query_course(self):
        """查询课程"""
        try:
            course_id = input_helper.get_input("请输入课程代码: ")
            course = self.data_manager.get_course(course_id)
            if course:
                self.display_manager.display_courses_table([course])
            else:
                self.message_manager.show_error(f"课程代码 {course_id} 不存在")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _display_all_courses(self):
        """显示所有课程"""
        try:
            self.display_manager.display_courses_table(self.data_manager.courses)
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _grade_management(self):
        """成绩管理"""
        while True:
            options = [
                "录入成绩",
                "查询成绩",
                "修改成绩",
                "删除成绩",
                "成绩统计",
                "GPA计算",
                "返回主菜单"
            ]
            print(self.menu_manager.show_submenu("成绩管理", options))
            choice = self.menu_manager.get_user_choice(7)
            
            if choice == 1:
                self._add_grade()
            elif choice == 2:
                self._query_grades()
            elif choice == 3:
                self._update_grade()
            elif choice == 4:
                self._delete_grade()
            elif choice == 5:
                self._grade_statistics()
            elif choice == 6:
                self._calculate_gpa()
            elif choice == 7:
                break
    
    def _add_grade(self):
        """录入成绩"""
        try:
            grade_data = self.form_manager.get_grade_input()
            grade = self.data_manager.add_grade(grade_data)
            self.data_manager.save_all_data()
            self.message_manager.show_success(f"成绩录入成功")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _query_grades(self):
        """查询成绩"""
        try:
            print("\n=== 查询成绩 ===")
            print("1. 按学号查询")
            print("2. 按课程查询")
            print("3. 按学期查询")
            print("4. 查询所有成绩")
            
            choice = self.menu_manager.get_user_choice(4)
            
            if choice == 1:
                student_id = input_helper.get_input("请输入学号: ")
                grades = self.data_manager.search_grades(student_id=student_id)
            elif choice == 2:
                course_id = input_helper.get_input("请输入课程代码: ")
                grades = self.data_manager.search_grades(course_id=course_id)
            elif choice == 3:
                semester = input_helper.get_input("请输入学期: ")
                grades = self.data_manager.search_grades(semester=semester)
            elif choice == 4:
                grades = self.data_manager.grades
            
            if grades:
                self.display_manager.display_grades_table(grades, self.data_manager.students, self.data_manager.courses)
            else:
                self.message_manager.show_info("未找到匹配的成绩记录")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _update_grade(self):
        """修改成绩"""
        try:
            student_id = input_helper.get_input("请输入学号: ")
            course_id = input_helper.get_input("请输入课程代码: ")
            semester = input_helper.get_input("请输入学期: ")
            exam_type = input_helper.get_input("请输入考试类型 [期末考试]: ") or "期末考试"
            
            # 查找成绩记录
            grade = None
            for g in self.data_manager.grades:
                if (g.student_id == student_id and g.course_id == course_id and 
                    g.semester == semester and g.exam_type == exam_type):
                    grade = g
                    break
            
            if not grade:
                raise DataNotFoundError("未找到匹配的成绩记录", "grade")
            
            print(f"当前成绩: {grade.score}")
            new_score = float(input_helper.get_input("请输入新成绩 (0-100): "))
            
            if not (0 <= new_score <= 100):
                raise ValidationError("成绩必须在0-100之间")
            
            grade.score = new_score
            self.data_manager.save_all_data()
            self.message_manager.show_success(f"成绩修改成功: {new_score}")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _delete_grade(self):
        """删除成绩"""
        try:
            student_id = input_helper.get_input("请输入学号: ")
            course_id = input_helper.get_input("请输入课程代码: ")
            semester = input_helper.get_input("请输入学期: ")
            exam_type = input_helper.get_input("请输入考试类型 [期末考试]: ") or "期末考试"
            
            # 查找并删除成绩记录
            for i, grade in enumerate(self.data_manager.grades):
                if (grade.student_id == student_id and grade.course_id == course_id and 
                    grade.semester == semester and grade.exam_type == exam_type):
                    if input_helper.confirm("确认删除该成绩记录？"):
                        del self.data_manager.grades[i]
                        self.data_manager.save_all_data()
                        self.message_manager.show_success("成绩删除成功")
                    return
            
            raise DataNotFoundError("未找到匹配的成绩记录", "grade")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _grade_statistics(self):
        """成绩统计"""
        try:
            if not self.data_manager.grades:
                self.message_manager.show_info("暂无成绩记录")
                return
            
            stats = self.statistics_calculator.calculate_grade_statistics(self.data_manager.grades)
            
            print("\n=== 成绩统计 ===")
            print(f"总成绩记录: {stats['total_count']} 条")
            print(f"最高分: {stats['score_stats']['max']:.1f}")
            print(f"最低分: {stats['score_stats']['min']:.1f}")
            print(f"平均分: {stats['score_stats']['mean']:.2f}")
            print(f"及格率: {stats['pass_rate']:.1f}%")
            
            print("\n等级分布:")
            for grade, count in stats['grade_distribution'].items():
                percentage = (count / stats['total_count']) * 100
                print(f"  {grade}: {count} 人 ({percentage:.1f}%)")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _calculate_gpa(self):
        """计算GPA"""
        try:
            print("\n=== GPA计算 ===")
            print("1. 计算单个学生GPA")
            print("2. 计算所有学生GPA")
            
            choice = self.menu_manager.get_user_choice(2)
            
            if choice == 1:
                student_id = input_helper.get_input("请输入学号: ")
                student = self.data_manager.get_student(student_id)
                if not student:
                    raise DataNotFoundError(f"学号 {student_id} 不存在", "student")
                
                grades = self.data_manager.search_grades(student_id=student_id, exam_type="期末考试")
                if not grades:
                    self.message_manager.show_info("该学生暂无期末考试成绩记录")
                    return
                
                # 计算GPA
                total_grade_points = 0
                total_credits = 0
                
                print(f"\n{student.name} ({student_id}) 的GPA计算：")
                print("-" * 80)
                print(f"{'课程代码':<10} {'课程名称':<15} {'成绩':<6} {'绩点':<6} {'学分':<6} {'加权绩点':<8}")
                print("-" * 80)
                
                for grade in grades:
                    course = self.data_manager.get_course(grade.course_id)
                    if course:
                        grade_point = grade.get_grade_point()
                        weighted_gp = grade_point * course.credits
                        total_grade_points += weighted_gp
                        total_credits += course.credits
                        
                        print(f"{course.course_id:<10} {course.course_name:<15} {grade.score:<6.1f} "
                              f"{grade_point:<6.1f} {course.credits:<6.1f} {weighted_gp:<8.2f}")
                
                print("-" * 80)
                
                if total_credits > 0:
                    gpa = total_grade_points / total_credits
                    print(f"总学分: {total_credits:.1f}")
                    print(f"总加权绩点: {total_grade_points:.2f}")
                    print(f"GPA: {gpa:.3f}")
                else:
                    self.message_manager.show_error("无法计算GPA：没有有效的课程学分信息")
            
            elif choice == 2:
                gpa_stats = self.statistics_calculator.calculate_gpa_statistics(
                    self.data_manager.students, 
                    self.data_manager.grades, 
                    self.data_manager.courses
                )
                
                if not gpa_stats:
                    self.message_manager.show_info("暂无可计算GPA的学生")
                    return
                
                print("\n=== 所有学生GPA ===")
                print("-" * 70)
                print(f"{'排名':<4} {'学号':<10} {'姓名':<8} {'专业':<15} {'GPA':<8} {'总学分':<8}")
                print("-" * 70)
                
                # 按GPA排序
                student_gpas = gpa_stats['student_gpas']
                sorted_gpas = sorted(student_gpas.items(), key=lambda x: x[1]['gpa'], reverse=True)
                
                for i, (student_id, info) in enumerate(sorted_gpas, 1):
                    student = self.data_manager.get_student(student_id)
                    major = student.major if student else "未知"
                    print(f"{i:<4} {student_id:<10} {info['student_name']:<8} {major:<15} "
                          f"{info['gpa']:<8.3f} {info['total_credits']:<8.1f}")
                
                print("-" * 70)
                print(f"共 {len(sorted_gpas)} 名学生")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _data_analysis(self):
        """数据分析"""
        while True:
            options = [
                "学生统计",
                "成绩统计",
                "生成图表",
                "生成报告",
                "返回主菜单"
            ]
            print(self.menu_manager.show_submenu("数据分析", options))
            choice = self.menu_manager.get_user_choice(5)
            
            if choice == 1:
                self._student_statistics()
            elif choice == 2:
                self._grade_statistics()
            elif choice == 3:
                self._generate_charts()
            elif choice == 4:
                self._generate_reports()
            elif choice == 5:
                break
    
    def _student_statistics(self):
        """学生统计"""
        try:
            stats = self.statistics_calculator.calculate_student_statistics(self.data_manager.students)
            self.display_manager.display_statistics(stats)
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _generate_charts(self):
        """生成图表"""
        try:
            print("\n=== 生成图表 ===")
            print("1. 专业分布图")
            print("2. 年龄分布图")
            print("3. 成绩分布图")
            
            choice = self.menu_manager.get_user_choice(3)
            
            if choice == 1:
                self.chart_generator.create_major_distribution_chart(
                    self.data_manager.students, 
                    "专业分布统计.png"
                )
            elif choice == 2:
                self.chart_generator.create_age_distribution_chart(
                    self.data_manager.students, 
                    "年龄分布统计.png"
                )
            elif choice == 3:
                self.chart_generator.create_grade_distribution_chart(
                    self.data_manager.grades, 
                    "成绩分布统计.png"
                )
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _generate_reports(self):
        """生成报告"""
        try:
            print("\n=== 生成报告 ===")
            print("1. 学生个人报告")
            print("2. 课程报告")
            print("3. 系统报告")
            
            choice = self.menu_manager.get_user_choice(3)
            
            if choice == 1:
                student_id = input_helper.get_input("请输入学号: ")
                report = self.report_generator.generate_student_report(student_id)
                filename = f"{student_id}_成绩报告.txt"
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write(report)
                self.message_manager.show_success(f"报告已生成: {filename}")
            elif choice == 2:
                course_id = input_helper.get_input("请输入课程代码: ")
                report = self.report_generator.generate_course_report(course_id)
                filename = f"{course_id}_课程报告.txt"
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write(report)
                self.message_manager.show_success(f"报告已生成: {filename}")
            elif choice == 3:
                report = self.report_generator.generate_system_report()
                filename = f"系统报告_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
                with open(filename, 'w', encoding='utf-8') as f:
                    f.write(report)
                self.message_manager.show_success(f"报告已生成: {filename}")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _data_import_export(self):
        """数据导入导出"""
        while True:
            options = [
                "导出到Excel",
                "从Excel导入",
                "导出到CSV",
                "从CSV导入",
                "数据备份",
                "数据恢复",
                "返回主菜单"
            ]
            print(self.menu_manager.show_submenu("数据导入导出", options))
            choice = self.menu_manager.get_user_choice(7)
            
            if choice == 1:
                self._export_to_excel()
            elif choice == 2:
                self._import_from_excel()
            elif choice == 3:
                self._export_to_csv()
            elif choice == 4:
                self._import_from_csv()
            elif choice == 5:
                self._backup_data()
            elif choice == 6:
                self._restore_data()
            elif choice == 7:
                break
    
    def _export_to_excel(self):
        """导出到Excel"""
        try:
            # 这里需要实现Excel导出功能
            self.message_manager.show_info("Excel导出功能开发中...")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _import_from_excel(self):
        """从Excel导入"""
        try:
            # 这里需要实现Excel导入功能
            self.message_manager.show_info("Excel导入功能开发中...")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _export_to_csv(self):
        """导出到CSV"""
        try:
            # 这里需要实现CSV导出功能
            self.message_manager.show_info("CSV导出功能开发中...")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _import_from_csv(self):
        """从CSV导入"""
        try:
            # 这里需要实现CSV导入功能
            self.message_manager.show_info("CSV导入功能开发中...")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _backup_data(self):
        """数据备份"""
        try:
            backup_path = self.data_manager.backup_data()
            self.message_manager.show_success(f"数据备份成功: {backup_path}")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _restore_data(self):
        """数据恢复"""
        try:
            backup_name = input_helper.get_input("请输入备份名称: ")
            # 这里需要实现数据恢复功能
            self.message_manager.show_info("数据恢复功能开发中...")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _system_settings(self):
        """系统设置"""
        try:
            self.message_manager.show_info("系统设置功能开发中...")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _show_system_status(self):
        """显示系统状态"""
        try:
            stats = self.data_manager.get_statistics()
            self.display_manager.display_statistics(stats)
            
            print(f"\n系统信息:")
            print(f"当前用户: {self.auth_manager.get_current_user().username if self.auth_manager.get_current_user() else '未登录'}")
            print(f"系统时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            print(f"Python版本: {sys.version}")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _view_personal_info(self):
        """查看个人信息（学生专用）"""
        try:
            current_user = self.auth_manager.get_current_user()
            if not current_user or current_user.role != 'student':
                raise PermissionError("权限不足")
            
            student = self.data_manager.get_student(current_user.student_id)
            if not student:
                raise DataNotFoundError("个人信息不存在", "student")
            
            print(f"\n=== 个人信息 ===")
            print(f"学号: {student.student_id}")
            print(f"姓名: {student.name}")
            print(f"年龄: {student.age}")
            print(f"专业: {student.major}")
            print(f"班级: {student.class_name}")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def _logout(self):
        """登出"""
        try:
            if self.auth_manager.logout():
                self.message_manager.show_success("登出成功")
            else:
                self.message_manager.show_error("登出失败")
        except Exception as e:
            self.message_manager.handle_exception(e)
    
    def shutdown(self):
        """关闭系统"""
        try:
            logger.info("正在关闭系统...")
            # 保存数据
            self.data_manager.save_all_data()
            # 清理资源
            self.auth_manager.cleanup_expired_sessions()
            logger.info("系统关闭完成")
        except Exception as e:
            logger.error(f"关闭系统时出错: {e}")


def main():
    """主函数"""
    try:
        system = StudentManagementSystem()
        system.run()
    except KeyboardInterrupt:
        print("\n程序被用户中断")
    except Exception as e:
        print(f"程序运行出错: {e}")
        logger.error(f"程序运行出错: {e}")


if __name__ == "__main__":
    main()
